---------------------------------------------------------------------------
--设置 require目录
function GetScriptPath()
    local info = debug.getinfo(GetScriptPath);
    return info.source:sub(2);
end

local function GetDir(v)
    local ps,pe,str = v:find('(.+[^/\\])[/\\][.%w%d%l_]+$');
    if(str==nil)then str = './' end;
    return str;
end

function GetScriptDir()
    return GetDir(GetScriptPath()) .. '/';
end

local dir = GetDir(GetScriptPath());

package.path = package.path .. ';' .. dir .. '/?.lua;'
--------------------------------------------------------------------------




require("system");
require('vkey');
print(require('emu.fceux'))
require('config.show');

View = require('view.render');



--test = 'gba';
test = 'gba';
if(arg and arg[1])then
    test = arg[1];
end

local last_time = 0;
local wait_time = 1000/60;
local rom = [[K:\git\gamev\a.gba]];

if(test=='gba')then
    
    if(ANDROID)then
        rom = GetScriptDir() .. 'a.gba';
    end
    --rom = [[d:\a.gba]];
    
    local window = CreateWindow(480,800);

    ----------------------------------------------------
    --有关显示的设置
    local size = {};
    local gameRect = {x = 0,y = 0};
    size.w,size.h = window:GetSize();
    --暂时用竖屏做判断
    local vscreen = true;

    if(vscreen)then
        --竖屏
        gameRect.w = size.w;
        gameRect.h = size.w * (160/240);
    else
        --横屏
        gameRect.h = size.h;
        gameRect.w = size.h * (240/160);
    end
    ---------------------------------------------------


    local vba;
    if(false)then
        vba = require('emu.vbam')
    else
        vba = require('emu.emu_ex_vba');
        print(rom);
    end

    local game = vba.LoadROM(rom);
    game:ReadSaveFile();

    local textListView = View.TextListView.new(window);
    local view = textListView;
    view.x = 100;
    view.y = 20;
    view.w = 500;
    view.h = 1500;
    view:SetSourceDrawPos(0,1000);
    view.textFont = {
        fontColor = 0xffffffff,
    }

    --当前视图,用来显示菜单
    local mainView = textListView;

    local function SaveListView(name,func,list)
        local saveListView = View.TextListView.new(window);
        saveListView.x = 100;
        saveListView.y = 20;
        saveListView.w = 500;
        saveListView.h = 1500;
        saveListView.textFont = {
            fontColor = 0xffffffff,
        }

        saveListView.texts = {};

        if(list)then
            for k,v in ipairs(list)do
                saveListView.texts[v.index] = {text=tostring(v.index),Click = function() _G[func](v.index); mainView = nil; end;};
            end
            for k=1,10 do
                if(saveListView.texts[k]==nil)then
                    saveListView.texts[k] = {text=" ",Click = function() _G[func](k); mainView = nil; end;};
                end
            end
            return saveListView;
        end

        for k=1,10 do
            --saveListView.texts[k] = {text='写入存档'..k,Click = function() SaveGameState(k); end;};
            if(list==nil)then
                saveListView.texts[k] = {text=name..tostring(k),Click = function() _G[func](k); mainView = nil; end;};
            end
        end
        return saveListView;
    end

    local stateList = game:GetSaveStateList();

    local saveListView = SaveListView('写入存档','SaveGameState',stateList);
    local loadListView = SaveListView('读取存档','LoadGameState',stateList);

    --  textListView.texts = {
    --  }

    textListView.texts = {
        {text='回到游戏',Click = function() mainView = nil; end},
        {text='加载游戏',Click = function() end },                    --游戏ROM文件
        {text='读取存档',Click = function() mainView = loadListView; end },                    --及时存档列表
        {text='保存存档',Click = function() mainView = saveListView; end },                    --及时存档列表
        {text='放大屏幕',Click = function() gameRect.w = gameRect.w + 10; gameRect.h = gameRect.w * (160/240) ;mainView = nil;  end},
        {text='缩小屏幕',Click = function() gameRect.w = gameRect.w - 10; gameRect.h = gameRect.w * (160/240);mainView = nil;  end},
        {text='退出游戏',Click = function() window.quit = true end}, --退出游戏
        {text='布局设置',Click = function() SetShowConfig(window,GetViews(),160/240); end},
    }

    --------------------------------------------------------
    --写入存档
    function SaveGameState(n)
        game:SaveState(n);
        if(loadListView.texts[n])then
            loadListView.texts[n].text = tostring(n);
            saveListView.texts[n].text = tostring(n);
        end
    end

    function LoadGameState(n)
        game:LoadState(n);
    end
    -----------------------------------------------------------------

    --创建虚拟按键
    local vpad = CreateGBAVKey(window);
    window:SetVPad(vpad);
    
    window.key = 0;
    local function setkey(v)
        window.key = bit.bor(window.key,v);
    end
    local function dpad(obj,x,y,w,h)
        local line = w / 3;
        if(x<line)then
            setkey(0x20);  --left;
        end
        if(x>line*2)then
            setkey(0x10); --right;
        end
        if(y<line)then
            setkey(0x40);
        end
        if(y>line*2)then
            setkey(0x80);
        end
    end
    local function select() setkey(0x4);end
    local function A() setkey(0x1); end
    local function B() setkey(0x2); end
    local function L() setkey(0x100); end
    local function R() setkey(0x200); end
    local function start() setkey(0x8);end

    --设置虚拟按键回调
    vpad:SetOnTouch(1,dpad);
    vpad:SetOnTouch(2,select);
    vpad:SetOnTouch(3,start);
    vpad:SetOnTouch(4,A);
    vpad:SetOnTouch(5,B);
    vpad:SetOnTouch(6,L);
    vpad:SetOnTouch(7,R);
    --结束设置虚拟按键


    ------------------------------------------------------------------------------
    --获得当前所有渲染的组建
    function GetViews()
        local views = {};
        --需要实现, Render, GetRenderRect,SetRenderRect 方法
        table.insert(views,window:GetRenderView(240,160,gameRect.x,gameRect.y,gameRect.w,gameRect.h));
        local v = views[1];
        function v:SetRenderRect(x,y,w,h)
            gameRect = {x=x,y=y,w=w,h=h};
        end

        local vkey = vpad:GetViews();
        for k,v in ipairs(vkey)do
            table.insert(views,v);
        end

        return views;
    end


    ---------------------------------------------------------------------------------


    function game:draw(pix,w,h,c)
        window:DrawPix32(pix,w+1,h,gameRect.x,gameRect.y,gameRect.w,gameRect.h);
    end

    function game:draw16(pix,w,h,c)
        --c == 16
        window:DrawPix16(pix,w,h,gameRect.x,gameRect.y,gameRect.w,gameRect.h);
    end

    function printf(format,...)
        io.stdout:write(string.format(format,...));
    end

    mainView = nil;

    window:SetEventCallBack(function(event)
        if(mainView)then
            mainView:Event(event)
        end
    end);

    local sound_pause = false;
    window:GameLoop(function(event)
        if(mainView)then
            if(ANDROID)then
                --安卓不实用Clear,会变成平铺效果
                window:RenderClear();
            end
                    --游戏菜单
            mainView:Render();
            --不执行后续的事件,虚拟按键的渲染
            --return false;
            SoundPause(1);
            sound_pause = true;
            return false;
        end
        if(sound_pause)then
            SoundPause(0);
            sound_pause = false;
        end

        
        window:RenderClear();
        local time1 = last_time;
        local speed = game:gameSpeed();

        local key = window:GetGameKey();
        local key2 = GetGameKey();
        key = bit.bor(key2,key);
        game:SetKey(key);

        ----------------------------------------------
        --调出菜单
        if(window:KeyState('Escape') or window:KeyState('AC Back'))then
            mainView = textListView;
        end

        -----------------------------------------------
        --判断是否游戏存档
        if(window:KeyState('f1'))then
            if(savestate==false)then
                if(window:KeyState('Left Shift'))then
                    game:SaveState(1);
                else
                    game:LoadState(1);
                end
            end
            savestate = true;
        else
            savestate = false;
        end
        
        --window:SetTitle(string.format( "%s%%",tostring(speed )));
        game:main();


        local time2 = GetTick();
        if((time2-time1)<wait_time)then
            Delay(2);
        end
        last_time = GetTick();
    end);

    --结束游戏
    game:WriteSaveFile();

elseif(test=='fc')then
    rom = 'l:/a.nes';
    fc:Init();
    if(ANDROID)then
        rom = GetScriptDir() .. 'a.nes';
    end
    local game = fc:LoadROM(rom);
    local window = CreateWindow(480,800);


    local vpad = CreateGBAVKey(window);
    window:SetVPad(vpad);
    
    window.key = 0;
    local function setkey(v)
        window.key = bit.bor(window.key,v);
    end
    local function dpad(obj,x,y,w,h)
        local line = w / 3;
        if(x<line)then
            setkey(0x40);  --left;
        end
        if(x>line*2)then
            setkey(0x80); --right;
        end
        if(y<line)then
            setkey(0x10);
        end
        if(y>line*2)then
            setkey(0x20);
        end
    end
    local function select() setkey(0x4);end
    local function A() setkey(0x1); end
    local function B() setkey(0x2); end
    local function L() setkey(0x100); end
    local function R() setkey(0x200); end
    local function start() setkey(0x8);end

    --设置虚拟按键回调
    vpad:SetOnTouch(1,dpad);
    vpad:SetOnTouch(2,select);
    vpad:SetOnTouch(3,start);
    vpad:SetOnTouch(4,A);
    vpad:SetOnTouch(5,B);
    vpad:SetOnTouch(6,L);
    vpad:SetOnTouch(7,R);
    --结束设置虚拟按键



    window:GameLoop(function()
        local time1 = last_time;
        game:Emulate();



        --更改按键设置
        -- local key = GetGameKey(function(setv)
        --     setv('a',0x100);
        --     setv('s',0x200);
        --     setv('z',0x1);
        --     setv('x',0x2);

        --     setv('space',0x4);
        --     setv('return',0x8);

        --     setv('left',0x40);
        --     setv('right',0x80);
        --     setv('up',0x10);
        --     setv('down',0x20);
        -- end);
        local pix = game:GetPix();
        window:DrawPix32(pix,256,240,(480-240)/2,0)
        local key = window:GetGameKey();
        game:SetKey(key);

        local pix,width,height = game:GetPix();

        local time2 = GetTick();
        -- if((time2-time1)<wait_time)then
        --     Delay(wait_time - (time2 - time1)-1);
        -- end
        last_time = GetTick();
    end);
end
